#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include "proto.h"
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#define NAMESIZE 1024

#define MSG_EXCEPT 020000
enum{
	STATE_SND=1,
	STATE_RCV,
	STATE_EX,
	STATE_T,
	STATE_OUTPUT,
};


struct ftp_c_st{
	int state;
	int id;
	union msg_un msg;	
	char fname[NAMESIZE];
	char errsoure[NAMESIZE];
	int flag;
};


static void driver(struct ftp_c_st* me){
	int ret;
	int len;
	switch(me->state){
		case STATE_SND:
			{
				if(me->flag){
					msg_path_t send;
					send.mtype=PATH;
					strncpy(send.path,me->fname,PATHSIZE);
					me->state=STATE_RCV;
					ret=msgsnd(me->id,&send,sizeof(send)-sizeof(long),0);
					if(ret<0){
						if(errno==EAGAIN||errno==EINTR){
							me->state=STATE_SND;
							return ;
						}
						else {
							strncpy(me->errsoure,"SNDmsgsnd",NAMESIZE);
							me->state=STATE_EX;
							return ;
						}
					}
					me->state=STATE_RCV;
					//me->flag=0;  先不发EOT
				}
				else{
					msg_eot_t eot1;
					eot1.mtype=EOT;
					ret=msgsnd(me->id,&eot1,sizeof(eot1)-sizeof(long),0);
					if(ret<0){
						if(errno==EAGAIN||errno==EINTR){
							me->state=STATE_SND;
							return ;
						}
						else {
							strncpy(me->errsoure,"SNDmsgsnd",NAMESIZE);
							me->state=STATE_EX;
							return ;
						}	
					}
					me->state=STATE_RCV;
				}
			}
			break;
		case STATE_RCV:
			ret=msgrcv(me->id,&me->msg,sizeof(msg_data_t)-sizeof(long),PATH,MSG_EXCEPT);
			if(ret<0){
				if(errno==EAGAIN||errno==EINTR){
					me->state=STATE_RCV;
				}
				else{
					strncpy(me->errsoure,"msgrcv",NAMESIZE);
					me->state=STATE_EX;
				}
			}
			if(me->msg.mtype==DATA)
				me->state=STATE_OUTPUT;
			if(me->msg.mtype==EOT){
				me->state=STATE_T;	
			}
			break;
		case STATE_EX:
			fprintf(stderr,"%s\n",me->errsoure);
			perror(" ");
			me->state=STATE_T;
			break;
		case STATE_T:
			break;
		case STATE_OUTPUT:
			fprintf(stdout,"%s",me->msg.datamsg.data);
			me->state=STATE_RCV;
			break;
		default:
			abort();
			break;
	}
	
}



int main(int argc,char* argv[]){
	if(argc<2){
		fprintf(stderr,"canshutaishao\n");
		exit(1);
	}
	struct ftp_c_st ftpc;

	int msgid;
	key_t key;
	key=ftok(KEYPATH,KEYPROJ);
	if(key<0){
		perror("ftok()");
		exit(1);
	}
	msgid=msgget(key,0);
	if(msgid<0){
		perror("msgget()");
		exit(1);
	}
	ftpc.state =STATE_SND;
	ftpc.id =msgid;
	ftpc.flag=1;
	strncpy(ftpc.fname,argv[1],NAMESIZE);
	while(ftpc.state!=STATE_T){
		driver(&ftpc);
	}
	printf("\nok!\n");
	exit(0);
}
